package org.wmq.positiontoshop.service;

import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.common.unit.DistanceUnit;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.MultiMatchQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.SearchHit;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.stereotype.Service;
import org.wmq.positiontoshop.model.ES.ShopES;
import org.wmq.positiontoshop.repository.ShopESRepository;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * Elasticsearch搜索服务
 * 提供各种基于Elasticsearch的店铺搜索功能
 */
@Service
@Slf4j
public class ElasticsearchSearchService {
    
    @Autowired
    private ShopESRepository shopESRepository;
    
    @Autowired
    private ElasticsearchRestTemplate elasticsearchRestTemplate;
    
    /**
     * 模糊搜索店铺（基于名称和描述）
     * 
     * @param keyword 搜索关键词
     * @return 匹配的店铺列表
     */
    public List<ShopES> searchShops(String keyword) {
        try {
            log.info("搜索店铺，关键词：{}", keyword);
            
            // 使用原生查询构建器构建复杂查询
            BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
            
            // 多字段匹配查询
            MultiMatchQueryBuilder multiMatchQuery = QueryBuilders.multiMatchQuery(keyword)
                    .field("name", 3.0f) // 名称字段权重更高
                    .field("description", 1.0f)
                    .field("address", 0.5f)
                    .type(MultiMatchQueryBuilder.Type.BEST_FIELDS)
                    .analyzer("ik_smart");
            
            queryBuilder.must(multiMatchQuery);
            
            // 只查询营业中的店铺
            queryBuilder.filter(QueryBuilders.termQuery("status", 1));
            
            // 构建查询
            NativeSearchQuery searchQuery = new NativeSearchQueryBuilder()
                    .withQuery(queryBuilder)
                    .withSort(SortBuilders.scoreSort().order(SortOrder.DESC)) // 按相关性得分排序
                    .withSort(SortBuilders.fieldSort("rating").order(SortOrder.DESC)) // 按评分排序
                    .build();
            
            // 执行查询
            SearchHits<ShopES> searchHits = elasticsearchRestTemplate.search(searchQuery, ShopES.class);
            
            // 处理结果
            return searchHits.getSearchHits().stream()
                    .map(SearchHit::getContent)
                    .collect(Collectors.toList());
        } catch (Exception e) {
            log.error("搜索店铺失败，关键词：{}", keyword, e);
            throw new RuntimeException("搜索店铺失败", e);
        }
    }
    
    /**
     * 高级搜索（支持多条件组合）
     * 
     * @param keyword 搜索关键词
     * @param type 店铺类型
     * @param minRating 最低评分
     * @param status 店铺状态
     * @return 匹配的店铺列表
     */
    public List<ShopES> advancedSearch(String keyword, String type, Double minRating, Integer status) {
        try {
            log.info("高级搜索店铺，关键词：{}, 类型：{}, 最低评分：{}, 状态：{}", 
                    keyword, type, minRating, status);
            
            BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
            
            // 如果有关键词，添加模糊匹配
            if (keyword != null && !keyword.isEmpty()) {
                MultiMatchQueryBuilder multiMatchQuery = QueryBuilders.multiMatchQuery(keyword)
                        .field("name", 3.0f)
                        .field("description", 1.0f)
                        .field("address", 0.5f)
                        .type(MultiMatchQueryBuilder.Type.BEST_FIELDS)
                        .analyzer("ik_smart");
                queryBuilder.must(multiMatchQuery);
            }
            
            // 如果有类型过滤
            if (type != null && !type.isEmpty()) {
                queryBuilder.filter(QueryBuilders.termQuery("type", type));
            }
            
            // 如果有评分过滤
            if (minRating != null) {
                queryBuilder.filter(QueryBuilders.rangeQuery("rating").gte(minRating));
            }
            
            // 如果有状态过滤
            if (status != null) {
                queryBuilder.filter(QueryBuilders.termQuery("status", status));
            }
            
            // 构建查询
            NativeSearchQuery searchQuery = new NativeSearchQueryBuilder()
                    .withQuery(queryBuilder)
                    .withSort(SortBuilders.scoreSort().order(SortOrder.DESC))
                    .withSort(SortBuilders.fieldSort("rating").order(SortOrder.DESC))
                    .build();
            
            // 执行查询
            SearchHits<ShopES> searchHits = elasticsearchRestTemplate.search(searchQuery, ShopES.class);
            
            // 处理结果
            return searchHits.getSearchHits().stream()
                    .map(SearchHit::getContent)
                    .collect(Collectors.toList());
        } catch (Exception e) {
            log.error("高级搜索店铺失败", e);
            throw new RuntimeException("高级搜索店铺失败", e);
        }
    }
    
    /**
     * 搜索附近的店铺（基于地理位置）
     * 
     * @param latitude 纬度
     * @param longitude 经度
     * @param distance 距离（单位：km）
     * @return 匹配的店铺列表
     */
    public List<ShopES> searchNearbyShops(Double latitude, Double longitude, Double distance) {
        try {
            log.info("搜索附近的店铺，纬度：{}, 经度：{}, 距离：{}km", 
                    latitude, longitude, distance);
            
            // 构建地理位置查询
            BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
            queryBuilder.filter(QueryBuilders.geoDistanceQuery("location")
                    .point(latitude, longitude)
                    .distance(distance, DistanceUnit.KILOMETERS));

            // 只查询营业中的店铺
            queryBuilder.filter(QueryBuilders.termQuery("status", 1));
            
            // 构建查询
            NativeSearchQuery searchQuery = new NativeSearchQueryBuilder()
                    .withQuery(queryBuilder)
                    .withSort(SortBuilders.geoDistanceSort("location", latitude, longitude)
                            .order(SortOrder.ASC) // 按距离升序排序
                            .unit(DistanceUnit.KILOMETERS))
                    .build();
            
            // 执行查询
            SearchHits<ShopES> searchHits = elasticsearchRestTemplate.search(searchQuery, ShopES.class);
            
            // 处理结果
            return searchHits.getSearchHits().stream()
                    .map(SearchHit::getContent)
                    .collect(Collectors.toList());
        } catch (Exception e) {
            log.error("搜索附近店铺失败", e);
            throw new RuntimeException("搜索附近店铺失败", e);
        }
    }
}